#ifndef __CM_NAT_WAN_P2P_DAEMON_H__
#define __CM_NAT_WAN_P2P_DAEMON_H__

#include "XMPPClient.h"
#include "IceLinkPool.h"
#include "JingleManager.h"
#include "MediaSession.h"

namespace cm_nat
{
    class WanP2PDaemon;

    class WanP2PDaemonListener
    {
    public:
        virtual void onReceive( WanP2PDaemon* p_wanP2P, ByteBuffer* data) =0;
        virtual void onState( WanP2PDaemon* p_wanP2P, int state ) =0;

    };

    class WanP2PDaemon : 
        public JingleManagerListener,
        public MediaSessionListener, 
        public IceLinkListener, 
        public XMPPClientListener
    {
    public:
        WanP2PDaemon();
        ~WanP2PDaemon();

        int setup(std::string username, std::string pwd, std::string server, UInt16 serverPort = 5222 );
        int teardown();

        void registerListener( WanP2PDaemonListener* p_listener );

        //each side exchange candidate
        int sendCandidate();
        //controlled side acknowledge the check result 
        //of controlling offered candidate
        int sendCheckConnectionResult();

        int send(ByteBuffer* data);

        //from JingleManagerListener
        void onSessionInitiate(JingleSession* p_js);
        void onSessionTerminate(JingleSession* p_js);

        //from MediaSessionListener
        void onInitiate( MediaSession* p_session ); 
        void onAccept( MediaSession* p_session );
        void onCandidate( MediaSession* p_session, Candidate* cand );
        void onCheckResult( MediaSession* p_session, int result );
        void onSelectCandidate( MediaSession* p_session, Candidate* cand );

        //from IceLinkListener
        void onReceive(IceLink* link, ByteBuffer* data);
        void onLinkState( IceLink* link, int state );

        //XMPPClientListener
        void onConnect( XMPPClient* client );
        void onDisconnect( XMPPClient* client );

        enum LinkCheckResult{
            LINK_CHECK_NULL,
            LINK_CHECK_FAIL,
            LINK_CHECK_SUCCESS
        };
       
    protected:
        std::string m_username;
        std::string m_resource;
        std::string m_password;
        std::string m_server;
        UInt16 m_serverPort;

        XMPPClient m_xmppClient;
        JingleManager m_jingleManager;

        MediaSession* m_mediaSessioin;

        IceLinkPool m_linkPool;
        
        IceLink* m_activeLink;
        IceLink* m_offerLink;
        IceLink* m_selectLink;

        WanP2PDaemonListener* m_listener;

        LinkCheckResult m_activeLinkCheckResult;

    };
}

#endif